<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head> 
<body>
  
</body>
</html>

<script type="text/javascript">
  // js有哪些遍历对象的方法
  // 1 可枚举所有 for(let key in obj) 任意顺序遍历所有可枚举属性(自身属性和原形创建属性) 通过hasOwnProperty只遍历自身属性
  // 2 可枚举自身 Object.entries/keys/values() 遍历对象自身的可枚举属性
  // 3 可不可枚举自身 Object.getOwnPropertyNames(targetObj) 获取对象自身的所有属性key组成的数组(包括不可枚举)
  // 4 可不可枚举所有 Reflect.ownKeys(targetObj) 获取所有属性key组成的数组(包括不可枚举 包括原形创建属性)

  // 作用域 作用域链
  // 1 作用域分为全局作用域，函数作用域，块级作用域(es5前通过匿名函数自我执行创建(例如jquery), es5之后通过{}加const/let(比如let在for中的应用))
  // 2 let/const在{}中是块级作用域(比如for)var不是, let不能变量提升var可以, const定义后就必须马上赋值并且后续不可更改
  // 3 程序从外到内执行, 变量从内到外查找(作用域链), 函数内部可以访问外部变量/外部不能访问内部变量(闭包 函数内return函数)
  // 4 this指向 一直往上找, 遇到function就指向这个function, 没有就指向window(比如外层都是箭头函数)

  // 深拷贝浅拷贝
  // 1 直接赋值: a = b 赋值了引用地址 指向同一个堆 相互影响
  // 2 浅拷贝: for in oldObj, newObj[i] = oldObj[i], 拷贝了一层, 如果oldObj[i]还是引用类型那还会互相影响
  // 3 深拷贝：for in oldObj, 基本数据类型newObj[i] = oldObj[i], 引用类型递归 newObj[i] = deepClone(oldObj[i])
  // 4 JSON.parse(JSON.stringify(item)) 深拷贝数组对象
  // 5 obj2 = { ...obj1 }只能拷贝一层, Object.assign({}, { name: 1 })只能拷贝一层

  // http1, https, http2
  // http1采用字符串传输 http2采用二进制帧流传输
  // http2支持多路复用 http一个链接只能提交一个请求而, http2一个链接能同时处理无数个请求, 可以降低连接数以提高网络的吞吐量
  // http2服务器客户端同时维护header信息, 后续传header索引id即可
  // http2支持服务端推送
  // 三次握手, 请求头: url/请求参数/method/header/content-type/cookie/cache-control/etag, 响应头/响应码/响应body
  // https: HTTP+SSL 三次握手变成多次握手添加链接加密 443端口 nginx配置
  // http1.1 -> https -> http2, 全链路生效才可以. 服务端配置开启http2, 客户端优先用http2如果没有降级http1.1

  // 介绍下前端的存储方式
  // 1 cookie 4k 20/domain header会带上 可设置过期时间
  // 2 localStorage 5M 永久 
  // 3 sessionStorage 5M 页面关闭后就没了
  // 4 indexedDB 非关系型数据库 存在硬盘 无限制

  // 1 in vue component, why data must be a function but not be a object
  function ComponentA(){
  }
  ComponentA.prototype.data = {
    count: 0
  }
  a1 = new ComponentA()
  a2 = new ComponentA()
  a1.data.count = 1111
  // a1.data and a2.data is the object which point the same address
  // when a1.data.count changed, a2.data.count will chaged as well
  console.log(a2.data.count)  // 1111
  // another
  function ComponentB(){
    this.data = this.data()
  }
  ComponentB.prototype.data = () => {
    return {
      count: 0
    }
  }
  b1 = new ComponentB()
  b2 = new ComponentB()
  // b1 and b2 are not the same this, so they returned obj point different address
  // b1.data's change will not influence b2.data
  b1.data.count = 22
  console.log(b2.data.count)  // 0

  // vue常用内置指令
  // v-model :value @input
  // v-if v-else v-elseif v-show
  // v-for v-slot v-cloak
  // v-text v-html

  // v-if v-for为什么不建议放同一个标签
  // v-for优先级高于v-if, 写在统一标签那每次循环都会判断if
  // v-for外边包一层template v-if
  // computed arr.filter内部处理

  // v-show算重排吗
  // v-if初始增删DOM, v-show display:none, 先渲染dom再css隐藏dom, 节点信息变化重新计算各节点和css, 算重排

  // v-for中的key有什么用, 为什么不推荐用随机数或者index
  // 1 diff操作更快, 相同key可以复用
  // 2 随机数每次都不同 相同key无法复用
  // 3 index增删节点后会变化, 同一元素渲染前后key不同了

  // vue的数据通信方式
  // props/$emit props父传子 子$emit子传父(子$emit方法到父用@接受)
  // $parent/$children, $ref访问dom元素/子组件, provide/inject, eventBus
  // vuex pina

  // vue2 数据响应式
  // 1 Observer 递归遍历data, 给this.data加上defineProperty get set
  // get: Dep.target && dep.addSub(Dep.target), return value
  // set: value = newValue, dep.notify()
  // defineProperty不支持数组 所以数组改成对象 并把数组方法全部重写了 所以改length等不能触发响应
  // 一开始就全递归加get set了, 所以后续添加data属性也不会触发响应 除非用$set $delete
  // 2 Vue 递归遍历data, 给this(Vue)加上defineProperty get set, 后续组件中字节用this.abc访问this.data.abc
  // 3 Compiler 递归遍历解析模板, 调用Watcher或者addEventListener
  // 4 Watcher Dep.target指向this 添加this.update方法
  // 5 Dep 创建subs数组(this.addSub) 执行所有项的this.update方法(this.notify())

  // vue3 数据响应式
  // 1 原始数据类型用ref(), 引用数据类型用reactive()
  // 2 new Proxy, get set delete返回Reflect get set delete, 不能在proxy内部再调用proxy所以用Reflect get等
  // 3 代理对象内部还有对象那递归再代理 按需递归
  // 4 如果代理对象上没有某个key 依然可以设置这个key的值
  // 5 支持数组 不需要再改造数组后重写所有数组方法
  // 6 WeakSet WeakMap 对象被代理后不会被重复代理

  // vue2和vue3的数据响应式原理有什么区别
  // 1 vue2使用Object.defineProperty()实现响应式原理，而vue3使用Proxy()实现。
  // 2 按需递归：面对对象嵌套都需要递归，但vue2是对对象的所有属性进行递归，vue3是按需递归，如果没有使用到内部对象的属性，就不需要递归，性能更好。
  // 3 可设置不存在key的值：vue2中，由于get set都是一开始就递归加上的, 所以初始data不存在的属性是不能触发响应的，而vue3可以。
  // 4 不需要重写数组方法：vue2对数组的实现是重写数组的所有方法，并改变，vue2中，数组的原型来实现，而Proxy则可以轻松实现。而且vue2中改变数组的长度是无效的，无法做到响应式，但vue3可以





</script>




